/////////////////////////////////////////////////////////////////////////////////////
// Header Protection
#ifndef _STRING_H_
#define _STRING_H_

/////////////////////////////////////////////////////////////////////////////////////
// Include Files
#include "Main\Definitions.h"

#include <windows.h> // for WideCharToMultiByte

/////////////////////////////////////////////////////////////////////////////////////
// Contains a character array and manipulates it as a single piece of data.
class string_t
{
public:     // methods

	// A constructor which create an empty string.
	string_t();

	// A constructor which creates a string from a single character.
	// _cText: char_t - the character to make into a string
	string_t( char_t _cText );

	// A constructor which creates a string from a character array.
	// _szText: char_t const * const - the character array to copy into a string
	string_t( char_t const * const _szText );

	// A constructor which creates a string from another string.
	// _strText: string_t const & - the string to copy.
	string_t( string_t const & _strText );

	// A constructor which creates a string from a multi-byte character array.
	// _szText: char const * const - the character array to copy into a string
	explicit string_t (char const * const _szText );

	// Destructor.
	~string_t() { if( m_szData ) delete[] m_szData; }

	// Copy a portion of the string.
	// _uStart: uint_t - the index at which to start copying
	// _uLength: uint_t - the number of characters to copy, if this is left out, 
	//     the string will be copied to the end
	// return: string_t - the string between the start and end indices
	string_t Substring( uint_t _uStart );
	string_t Substring( uint_t _uStart, uint_t _uLength );

	// Find the first instance of a character within the string
	// _cSearch: char_t - the character to look for
	// _uStart: uint_t - the index in the string at which to start the search, if 
	//     this is left out, the search will start at the beginning of the string
	// return: int_t - the index of the first time the character appears in the 
	//     string, or -1 if it does not appear
	int_t IndexOf( char_t _cSearch );
	int_t IndexOf( char_t _cSearch, uint_t _uStart );

	// Find the last instance of a character within the string
	// _char: char_t - the character to look for
	// _cSearch: uint_t - the index in the string at which to start the search, if 
	//     this is left out, the search will start at the end of the string
	// return: int_t - the index of the last time the character appears in the 
	//     string, or -1 if it does not appear
	int_t LastIndexOf( char_t _cSearch );
	int_t LastIndexOf( char_t _cSearch, uint_t _uStart );

	// Converts this string to multi-byte. Call with a CE_NULL buffer in order to 
	//     find the required buffer size.
	// _szBuffer: char * - the buffer to fill with the multi-byte string
	// _uBufferSize: uint_t - the size of the buffer
	// return: int_t - the size in bytes of the converted string.
	inline int_t ToMultiByte( char * _szBuffer, uint_t _uBufferSize )
	{
		return WideCharToMultiByte( 
			CP_UTF8, 0, m_szData, m_uLength, _szBuffer, _uBufferSize, 0, 0 
		);
	}

public:     // operators

	// Make this string a copy of another character, character array, or string.
	// return: string_t & - this string
	string_t & operator =( char_t _cText );
	string_t & operator =( char_t const * const _szText );
	string_t & operator =( string_t const & _strText );

	// Retrieve the character at the given index.
	// _iIndex: uint_t - the index to get the character from
	// return: char_t const & - the character at the given index
	char_t const & operator [] ( uint_t _iIndex ) const { return m_szData[_iIndex]; }

	// retrieve the internal character array for reading
	// return: char_t const * - the internal string data
	operator char_t const *() const { return m_szData; }

	// Concatenate this string and another character, character array, or string
	// return: string_t - a new string created from the string and text
	string_t operator +( char_t _cText );
	string_t operator +( char_t const *_szText );
	string_t operator +( string_t const &_strText );
	friend string_t operator +( char_t _cText, string_t const &_strText );
	friend string_t operator +( char_t const *_szText, string_t const &_strText );

	// Append another character, character array, or string to this one
	// return: string_t & - this string after the given text is appended
	string_t & operator +=( char_t _cText );
	string_t & operator +=( char_t const *_szText );
	string_t & operator +=( string_t const &_strText );

	// Compare this string with another character, character array, or string.
	// return: bool_t - the result of the comparison
	bool_t operator ==( char_t _cText );
	bool_t operator ==( char_t const * _szText );
	bool_t operator ==( string_t const & _strText );
	friend bool_t operator ==( char_t _cText, string_t const & _strText );
	friend bool_t operator ==( char_t const * _szText, string_t const & _strText );

	bool_t operator !=( char_t _cText );
	bool_t operator !=( char_t const * _szText );
	bool_t operator !=( string_t const & _strText );
	friend bool_t operator !=( char_t _cText, string_t const & _strText );
	friend bool_t operator !=( char_t const * _szText, string_t const & _strText );

	bool_t operator >( char_t _cText );
	bool_t operator >( char_t const * _szText );
	bool_t operator >( string_t const & _strText );
	friend bool_t operator >( char_t _cText, string_t const & _strText );
	friend bool_t operator >( char_t const * _szText, string_t const & _strText );

	bool_t operator <( char_t _cText );
	bool_t operator <( char_t const * _szText );
	bool_t operator <( string_t const & _strText );
	friend bool_t operator <( char_t _cText, string_t const & _strText );
	friend bool_t operator <( char_t const * _szText, string_t const & _strText );

	bool_t operator >=( char_t _cText );
	bool_t operator >=( char_t const * _szText );
	bool_t operator >=( string_t const & _strText );
	friend bool_t operator >=( char_t _cText, string_t const & _strText );
	friend bool_t operator >=( char_t const * _szText, string_t const & _strText );

	bool_t operator <=( char_t _cText );
	bool_t operator <=( char_t const * _szText );
	bool_t operator <=( string_t const & _strText );
	friend bool_t operator <=( char_t _cText, string_t const & _strText );
	friend bool_t operator <=( char_t const * _szText, string_t const & _strText );

private:    // data
	uint_t   m_uLength;
	char_t * m_szData;
};

/////////////////////////////////////////////////////////////////////////////////////
// Header Protection
#endif // _STRING_H_
